package com.infore.dataReceiving.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.infore.dataReceiving.constant.Constants;
import com.infore.dataReceiving.dto.ManualDataDto;
import com.infore.dataReceiving.entity.HourData;
import com.infore.dataReceiving.entity.ManualData;
import com.infore.dataReceiving.enums.ResultStatus;
import com.infore.dataReceiving.repository.IHourDataRepository;
import com.infore.dataReceiving.repository.IManualDataRepository;
import com.infore.dataReceiving.service.IManualDataService;
import com.infore.dataReceiving.util.DateUtil;
import com.infore.dataReceiving.util.ResultEntity;

@Service
public class ManualDataServiceImpl implements IManualDataService {
    
    @Autowired
    IManualDataRepository IManualDataRepository;
    
    @Autowired
    IHourDataRepository iHourDataRepository;
    
    public static final List<String> indexCodeList = new ArrayList<String>(Arrays.asList("w01019","w21003","w21011","w21001"
            ,"w01001","w01010","w01009","w01014","w01003"));

    @Override
    public ResultEntity saveManualData(ManualDataDto manualDataDto) {
        String dataTime = manualDataDto.getDataTime();
        Date date = DateUtil.stringToDate(dataTime, DateUtil.DATE_FULL_STR);
        String stationCode = manualDataDto.getStationCode();
        String dataType = manualDataDto.getDataType();
        for (String string : indexCodeList) {
            ManualData manualData = new ManualData();
            manualData.setStationCode(stationCode);
            manualData.setDataTime(date);
            String value = "";
            if ("w01019".equals(string)) {
                value = manualDataDto.getW01009();
            } else if ("w21003".equals(string)) {
                value = manualDataDto.getW21003();
            } else if ("w21011".equals(string)) {
                value = manualDataDto.getW21011();
            } else if ("w21001".equals(string)) {
                value = manualDataDto.getW21001();
            } else if ("w01001".equals(string)) {
                value = manualDataDto.getW01001();
            } else if ("w01010".equals(string)) {
                value = manualDataDto.getW01010();
            } else if ("w01009".equals(string)) {
                value = manualDataDto.getW01009();
            } else if ("w01014".equals(string)) {
                value = manualDataDto.getW01014();
            } else if ("w01003".equals(string)) {
                value = manualDataDto.getW01003();
            }
            if (value == null) { // 空值不保存
                continue;
            }
            manualData.setValue(value);
            manualData.setFactorCode(string);
            manualData.setDataType(dataType);
            IManualDataRepository.saveAndFlush(manualData);
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.DEAL_SUCCESS);
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity queryManualData(String stationCode, String startTime, String endTime) {
        Date startDate = DateUtil.stringToDate(startTime, DateUtil.DATE_FULL_STR);
        Date endDate = DateUtil.stringToDate(endTime, DateUtil.DATE_FULL_STR);
        List<ManualData> list = IManualDataRepository.findByDataTimeBetweenAndStationCode(startDate, endDate, stationCode);
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Map<String, Object> iMap = new HashMap<String, Object>();
        for (ManualData manualData : list) {
            String station = manualData.getStationCode();
            String factor = manualData.getFactorCode();
            String value = manualData.getValue();
            String date = DateUtil.dateToString(manualData.getDataTime(), DateUtil.DATE_FULL_STR);
            String dataType = manualData.getDataType();
            if (!iMap.containsKey(station + date)) {
                resultMap = new HashMap<String, Object>();
                resultMap.put("DATA_TYPE", dataType);
                resultMap.put("TIME", date);
                resultMap.put(factor, value);
                result.add(resultMap);
                iMap.put(station + date, resultMap);
            } else {
                resultMap = (Map<String, Object>) iMap.get(station + date);
                resultMap.put(factor, value);
            }
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

    @SuppressWarnings("unchecked")
    @Override
    public ResultEntity comparisonData(String stationCode, String time) {
        Date date = DateUtil.stringToDate(time, DateUtil.DATE_FULL_STR);
        // 获取手工数据
        List<ManualData> manualList = IManualDataRepository.findByDataTimeAndStationCode(date, stationCode);
        // 获取自动数据
        List<HourData> hourList = iHourDataRepository.findByDataTimeAndMn(date, stationCode);
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Map<String, Object> iMap = new HashMap<String, Object>();
        for (ManualData manualData : manualList) {
            String station = manualData.getStationCode();
            String factor = manualData.getFactorCode();
            String manualValue = manualData.getValue();
            String dateTime = DateUtil.dateToString(manualData.getDataTime(), DateUtil.DATE_FULL_STR);
            List<String> realValue = hourList.stream().filter(l -> factor.equals(l.getFactorCode())).map(HourData::getValue).collect(Collectors.toList());
            String value = "";
            if (realValue.size() > 0) {
                value = realValue.get(0);
            }
            if (!iMap.containsKey(station + dateTime)) {
                resultMap = new HashMap<String, Object>();
                resultMap.put("TIME", dateTime);
                resultMap.put(factor + "_manual", manualValue);
                resultMap.put(factor + "_real", value);
                result.add(resultMap);
                iMap.put(station + dateTime, resultMap);
            } else {
                resultMap = (Map<String, Object>) iMap.get(station + dateTime);
                resultMap.put(factor + "_manual", manualValue);
                resultMap.put(factor + "_real", value);
            }
        }
        return new ResultEntity(ResultStatus.SUCCESS, Constants.QUERY_SUCCESS).setDataList(result);
    }

}
